// 从socket缓冲区中读取数据的解析类
package com.tool;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class MessageBuffer {

	byte[] buffer;

	InputStream instream;

	int bufferpos;

	int bufferlen;

	public MessageBuffer(InputStream in, int size) {
		this.instream = in;
		buffer = new byte[size];
	}

	// 从buf中一直读数据，直到读到equals字节为止
	public boolean readEqual(ByteArrayOutputStream bos, byte equals)
			throws IOException {
		int noRead = 0;
		int equalLoc = -1;
		do {
			while (!hasBufferedData()) {
				noRead = fillBuffer();
				if (noRead == -1)
					return false;
			}
			if ((equalLoc = serachBytes(equals)) == -1) {
				byte[] buff = consumeBufferAll(bos != null);
				if (bos != null && buff != null) {
					bos.write(buff);
				}
			} else {
				byte[] buff = consumeBuffer(bos != null, equalLoc - bufferpos
						+ 1);
				if (bos != null && buff != null) {
					bos.write(buff);
				}
				break;
			}
		} while (true);

		return true;
	}

	public boolean readEqual(byte equals) throws IOException {
		return readEqual(null, equals);
	}

	// 读出length字节的数据到bos中
	public boolean readFillLength(ByteArrayOutputStream bos, int length)
			throws IOException {
		if(length <= 0)
		{
			return true;
		}
		int noRead = 0;
		int readLength = 0;
		boolean isFill = false;
		do {
			while (!hasBufferedData()) {
				noRead = fillBuffer();
				if (noRead == -1)
					return false;
			}

			byte[] buff = null;
			if (length - readLength > getTotalLength()) {
				buff = consumeBufferAll(true);
			} else {
				buff = consumeBuffer(true, length - readLength);
				isFill = true;
			}
			bos.write(buff);
			readLength += buff.length;
			if (isFill) {
				break;
			}
		} while (true);

		return true;
	}

	// 读出buf中的所有数据
	private byte[] consumeBufferAll(boolean isConsume) {
		return consumeBuffer(isConsume, getTotalLength());
	}

	// 读出length个字节，由isConsume控制是否返回读出的字节
	private byte[] consumeBuffer(boolean isConsume, int length) {
		byte[] consumes = null;
		if (isConsume) {
			System.arraycopy(buffer, bufferpos, consumes = new byte[length], 0,
					length);
		}
		bufferpos += length;
		return consumes;
	}

	// 获取buf中的字节数
	private int getTotalLength() {
		return bufferlen - bufferpos;
	}

	// 读出一个字节，并将其转换成int返回
	public byte read() throws IOException {
		while (!hasBufferedData()) {
			int noRead = fillBuffer();
			if (noRead == -1) {
				return -1;
			}
		}
		return this.buffer[this.bufferpos++];
	}

	// 查找buf中的字符equals，返回该字符的位置
	private int serachBytes(byte equals) {
		for (int start = bufferpos; start < bufferlen; start++) {
			if (buffer[start] == equals) {
				return start;
			}
		}
		return -1;
	}

	// 从buf中读取数据到b中
	public int read(final byte[] b, int off, int len) throws IOException {
		if (b == null || off == len) {
			return 0;
		}
		int noRead = 0;
		while (!hasBufferedData()) {
			noRead = fillBuffer();
			if (noRead == -1) {
				return -1;
			}
		}
		int chunk = this.bufferlen - this.bufferpos;
		if (chunk > len) {
			chunk = len;
		}
		System.arraycopy(this.buffer, this.bufferpos, b, off, chunk);
		this.bufferpos += chunk;
		return chunk;
	}

	// 从buf中读取数据到b中
	public int read(final byte[] b) throws IOException {
		if (b == null) {
			return 0;
		}
		return read(b, 0, b.length);
	}

	// 从缓冲区中读取数据，将buf填满
	private int fillBuffer() throws IOException {
		// compact the buffer if necessary
		if (this.bufferpos > 0) {
			int len = this.bufferlen - this.bufferpos;
			if (len > 0) {
				System.arraycopy(this.buffer, this.bufferpos, this.buffer, 0,
						len);
			}
			this.bufferpos = 0;
			this.bufferlen = len;
		}
		int l;
		int off = this.bufferlen;
		int len = this.buffer.length - off;
		l = this.instream.read(this.buffer, off, len);
		if (l == -1) {
			return -1;
		} else {
			this.bufferlen = off + l;
			return l;
		}
	}

	// buf中是否有数据
	private boolean hasBufferedData() {
		return this.bufferpos < this.bufferlen;
	}

}
